package com.wuhanins.insmytestdemo.app.activity;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;

import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.blankj.utilcode.util.NetworkUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.wuhanins.common.utils.INSLog;
import com.wuhanins.core.promise.JPromiser;
import com.wuhanins.core.promise.JPromiserQueue;
import com.wuhanins.core.promise.Promiser;
import com.wuhanins.http.volley.WebApiVolleyHelper;
import com.wuhanins.http.volley.v3.IOnProxyDoneListener_v3;
import com.wuhanins.insmytestdemo.R;
import com.wuhanins.insmytestdemo.base.BaseActivity;
import com.wuhanins.insmytestdemo.databinding.ActivityLocationBinding;
import com.wuhanins.insmytestdemo.domainService.provider.MiPContext;
import com.wuhanins.insmytestdemo.extend.webApiProxy.insSysProxy.getCircleRangeProxy.GetCircleRangeOutput;
import com.wuhanins.insmytestdemo.extend.webApiProxy.insSysProxy.getCircleRangeProxy.GetCircleRangePInput;
import com.wuhanins.insmytestdemo.extend.webApiProxy.insSysProxy.getCircleRangeProxy.GetCircleRangeProxyApi;
import com.wuhanins.insmytestdemo.extend.webApiProxy.insSysProxy.getFenceRangeProxy.GetFenceRangeOutput;
import com.wuhanins.insmytestdemo.extend.webApiProxy.insSysProxy.getFenceRangeProxy.GetFenceRangePInput;
import com.wuhanins.insmytestdemo.extend.webApiProxy.insSysProxy.getFenceRangeProxy.GetFenceRangeProxyApi;

import java.util.ArrayList;

/**
 * @author: Gab
 * @Project: fileService
 * @Pcakage: com.wuhanins.insmytestdemo.ui.activity.BDLocationActivity
 * @Date: 2023年08月31日 09:28
 * @Description: 本地通过接口上传定位信息
 */
public class BDLocationActivity extends BaseActivity<ActivityLocationBinding> {

    private ArrayList<JPromiser> task;
    public LocationClient mLocationClient = null;
    private int scanSpanTime = 0;
    private String Radius = "50";
    private boolean isStart = false;

    public static void start(Context context) {
        Intent starter = new Intent(context, BDLocationActivity.class);
        context.startActivity(starter);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(ActivityLocationBinding.class);
        LocationClient.setAgreePrivacy(true);
    }

    public Toolbar getToolbar() {
        return binding.toolbar;
    }

    public  class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            //此处的BDLocation为定位结果信息类，通过它的各种get方法可获取定位相关的全部结果
            //以下只列举部分获取经纬度相关（常用）的结果信息
            //更多结果信息获取说明，请参照类参考中BDLocation类中的说明
            String floor = location.getFloor();
            INSLog.e("floor", floor);
            double latitude = location.getLatitude();    //获取纬度信息
            double longitude = location.getLongitude();    //获取经度信息
            float radius = location.getRadius();    //获取定位精度，默认值为0.0f
            String nowDate = TimeUtils.date2String(TimeUtils.getNowDate());
            String coorType = location.getCoorType();
            //获取经纬度坐标类型，以LocationClientOption中设置过的坐标类型为准
            String addr = location.getAddrStr();    //获取详细地址信息
            String country = location.getCountry();    //获取国家
            String province = location.getProvince();    //获取省份
            String city = location.getCity();    //获取城市
            String district = location.getDistrict();    //获取区县
            String street = location.getStreet();    //获取街道信息
            String adcode = location.getAdCode();    //获取adcode
            String town = location.getTown();    //获取乡镇信息
            int errorCode = location.getLocType();

            INSLog.e("logan", "纬度:" + latitude + " 经度:" + longitude);
            INSLog.e("logan", "时间:" + nowDate);
            INSLog.e("logan", "地点:" + addr);

            String resolve = "纬度: " + latitude + "\n 经度: " + longitude + "\n 时间: " + nowDate + "\n 地点: " + addr;
            binding.tvLocation.setText(resolve);
            //获取定位类型、定位错误返回码，具体信息可参照类参考中BDLocation类中的说明
            Promiser fenceRange = getRoundness(String.valueOf(latitude), String.valueOf(longitude), Radius, addr);
            INSLog.e("Radius", Radius);
            Promiser q = new Promiser() {
                @Override
                protected void aync(Deffered<String, String> d) {
                    boolean safeString = getWallet().getSafeBoolean(WALLET_ROUNDNESS);
                    if (safeString) {
                        binding.tvScope.setTextColor(Color.BLACK);
                    } else {
                        binding.tvScope.setTextColor(Color.RED);
                    }
                    binding.tvScope.setText(safeString ? "当前获取坐标在设定围栏内,可以进行打卡操作" : "当前获取坐标不在设定围栏内,无法进行打卡操作");
//                    ToastUtils.showLong(safeString ? "获取坐标在围栏内" : "获取坐标不在围栏内");
                    d.resolve();
                }
            };
            JPromiserQueue.newInstance().sync(fenceRange, q).run();
        }
    }

    @Override
    protected void iView() {
        binding.toolbar.setTitle("百度定位");
        setSupportActionBar(binding.toolbar);
        if (getToolbar() != null) {
            getToolbar().setNavigationIcon(R.mipmap.back);
            getToolbar().setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finish();
                }
            });
        }
    }

    @Override
    protected void iData() {
        task = new ArrayList<>();
    }

    public void startRoundness(View view) {
        if (!NetworkUtils.isConnected()) {
            ToastUtils.showLong("请检查网络是否正常！");
            return;
        }
        if (!checkGPSIsOpen(this)) {
            new AlertDialog.Builder(this, R.style.Theme_AppCompat_Light_Dialog_Alert)
                    .setMessage("开启围栏范围查询需要开启GPS，是否打开GPS")
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                            intentActivityResultLauncher.launch(intent);
                        }
                    }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            }).show();
            return;
        }
        if (isStart) {
            ToastUtils.showLong("服务开启中,请先关闭围栏范围查询");
            return;
        }
        scanSpanTime = 0;
        boolean isScanSpanTime = binding.etScanSpanTime.getText().toString().isEmpty();
        boolean isRadius = binding.etRadius.getText().toString().isEmpty();
        if (!isScanSpanTime) {
            scanSpanTime = Integer.parseInt(binding.etScanSpanTime.getText().toString());
        } else {
            ToastUtils.showLong("请设置发起定位请求的时间间隔");
            return;
        }
        if (!isRadius) {
            Radius = binding.etRadius.getText().toString();
        }
        isStart = true;
        mLocationClient = new LocationClient(this);
        //声明LocationClient类
        MyLocationListener myListener = new MyLocationListener();
        mLocationClient.registerLocationListener(myListener);
        BDLocation(scanSpanTime * 1000);
        closeSoftInput();
    }

    public void stopRoundness(View view) {
        isStart = false;
        BDDisableBackgroundLocation();
    }

    public void BDDisableBackgroundLocation() {
        if (mLocationClient != null) {
            //关闭后台定位（true：通知栏消失；false：通知栏可手动划除）
            mLocationClient.disableLocInForeground(true);
            mLocationClient.stop();
            mLocationClient = null;
            ToastUtils.showLong("定位请求关闭成功");
        }
    }

    private final ActivityResultLauncher<Intent> intentActivityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
        @Override
        public void onActivityResult(ActivityResult result) {

        }
    });

    public static boolean checkGPSIsOpen(Context context) {
        LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        //return locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER);
        // 通过GPS卫星定位，定位级别可以精确到街（通过24颗卫星定位，在室外和空旷的地方定位准确、速度快）
        boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        // 通过WLAN或移动网络(3G/2G)确定的位置（也称作AGPS，辅助GPS定位。主要用于在室内或遮盖物（建筑群或茂密的深林等）密集的地方定位）
        boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        return gps || network;
    }

    public void BDLocation(int ScanSpan) {
        LocationClientOption option = new LocationClientOption();

        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选，设置定位模式，默认高精度
        //LocationMode.Hight_Accuracy：高精度；
        //LocationMode. Battery_Saving：低功耗；
        //LocationMode. Device_Sensors：仅使用设备；
        //LocationMode.Fuzzy_Locating, 模糊定位模式；v9.2.8版本开始支持，可以降低API的调用频率，但同时也会降低定位精度；

        option.setCoorType("bd09ll");
        //可选，设置返回经纬度坐标类型，默认GCJ02
        //GCJ02：国测局坐标；
        //BD09ll：百度经纬度坐标；
        //BD09：百度墨卡托坐标；
        //海外地区定位，无需设置坐标类型，统一返回WGS84类型坐标

        option.setFirstLocType(LocationClientOption.FirstLocType.SPEED_IN_FIRST_LOC);
        //可选，首次定位时可以选择定位的返回是准确性优先还是速度优先，默认为速度优先
        //可以搭配setOnceLocation(Boolean isOnceLocation)单次定位接口使用，当设置为单次定位时，setFirstLocType接口中设置的类型即为单次定位使用的类型
        //FirstLocType.SPEED_IN_FIRST_LOC:速度优先，首次定位时会降低定位准确性，提升定位速度；
        //FirstLocType.ACCUARACY_IN_FIRST_LOC:准确性优先，首次定位时会降低速度，提升定位准确性；

        option.setScanSpan(ScanSpan);
        //可选，设置发起定位请求的间隔，int类型，单位ms
        //如果设置为0，则代表单次定位，即仅定位一次，默认为0
        //如果设置非0，需设置1000ms以上才有效

        option.setOpenGnss(true);
        //可选，设置是否使用卫星定位，默认false
        //使用高精度和仅用设备两种定位模式的，参数必须设置为true

        option.setLocationNotify(true);
        //可选，设置是否当卫星定位有效时按照1S/1次频率输出卫星定位结果，默认false

        option.setIgnoreKillProcess(true);
        //可选，定位SDK内部是一个service，并放到了独立进程。
        //设置是否在stop的时候杀死这个进程，默认（建议）不杀死，即setIgnoreKillProcess(true)

        option.SetIgnoreCacheException(false);
        //可选，设置是否收集Crash信息，默认收集，即参数为false

        option.setWifiCacheTimeOut(5 * 60 * 1000);
        //可选，V7.2版本新增能力
        //如果设置了该接口，首次启动定位时，会先判断当前Wi-Fi是否超出有效期，若超出有效期，会先重新扫描Wi-Fi，然后定位

        option.setEnableSimulateGnss(false);
        //可选，设置是否需要过滤卫星定位仿真结果，默认需要，即参数为false

        option.setNeedNewVersionRgc(true);
        //可选，设置是否需要最新版本的地址信息。默认需要，即参数为true

        option.setIsNeedAddress(true);
        //可选，是否需要地址信息，默认为不需要，即参数为false
        //如果开发者需要获得当前点的地址信息，此处必须为true

        option.setNeedNewVersionRgc(true);
        //可选，设置是否需要最新版本的地址信息。默认需要，即参数为true

        mLocationClient.setLocOption(option);
        //mLocationClient为第二步初始化过的LocationClient对象
        //需将配置好的LocationClientOption对象，通过setLocOption方法传递给LocationClient对象使用
        //更多LocationClientOption的配置，请参照类参考中LocationClientOption类的详细说明

        mLocationClient.setLocOption(option);
        //mLocationClient为第二步初始化过的LocationClient对象
        //需将配置好的LocationClientOption对象，通过setLocOption方法传递给LocationClient对象使用
        //更多LocationClientOption的配置，请参照类参考中LocationClientOption类的详细说明
        mLocationClient.start();
    }

    public final static String WALLET_FENCE_RANGE = "BDLocationActivity.getFenceRange_data";
    public final static String WALLET_ROUNDNESS = "BDLocationActivity.getRoundness_data";

    public Promiser getFenceRange(String Lat, String Lon) {
        GetFenceRangeProxyApi proxyApi = new GetFenceRangeProxyApi(MiPContext.getInstance());
        GetFenceRangePInput input = new GetFenceRangePInput();
        input.setLatitude(Lat);
        input.setLongitude(Lon);
        return proxyApi.$doRequest(WebApiVolleyHelper.sharedRequestQueue(), input, new IOnProxyDoneListener_v3<GetFenceRangeOutput>() {
            @Override
            public void done() {

            }

            @Override
            public boolean error(int code, String message, int type) {
                return false;
            }

            @Override
            public void success(GetFenceRangeOutput getFenceRangeOutput) {
                getWallet().putExtra(WALLET_FENCE_RANGE, getFenceRangeOutput.getContent());
            }
        });
    }

    public Promiser getRoundness(String Lat, String Lon, String Radius, String Location) {
        GetCircleRangeProxyApi proxyApi = new GetCircleRangeProxyApi(MiPContext.getInstance());
        GetCircleRangePInput input = new GetCircleRangePInput();
        input.setCurrentLatitude(Double.parseDouble(Lat));
        input.setCurrentLongitude(Double.parseDouble(Lon));
//        input.setLatitude1(30.54238);
//        input.setLongitude1(114.36210);
//        input.setLatitude2(30.54261);
//        input.setLongitude2(114.36177);
        input.setRadius(Radius);
        input.setLocation(Location);
        input.setUserId("350718d9-b24c-441d-bd1f-85464b65dc2f");
        return proxyApi.$doRequest(WebApiVolleyHelper.sharedRequestQueue(), input, new IOnProxyDoneListener_v3<GetCircleRangeOutput>() {
            @Override
            public void done() {

            }

            @Override
            public boolean error(int code, String message, int type) {
                ToastUtils.showLong(message);
                return false;
            }

            @Override
            public void success(GetCircleRangeOutput getCircleRangeOutput) {
                getWallet().putExtra(WALLET_ROUNDNESS, getCircleRangeOutput.getContent());
            }
        });
    }
}